﻿
using Sys;

using System.Silverlight;
using System.Silverlight.Presentation;
using System.Silverlight.Presentation.Animation;
using System;
using seh = Sys.EventHandler;
using sea = Sys.EventArgs;

namespace SBT
{
    

    
    public class ScrollContainer : AgBehavior
    {
        private seh m_onContentSizeChangedHandler;
        private seh m_onContentBoxTranslateXChangedHandler;
        private seh m_onContentBoxTranslateYChangedHandler;
        private Translatable m_contentBox;
        public  bool IsReady
        {
            get { return base.IsInitialized; }
        }
        public string ContentBoxName
        {
            get
            {
                return m_contentBox.ElementName;
            }
        }
        private IScroller m_scroller;
        public IScroller Scroller
        {
            get
            {
                return m_scroller;
            }
            set
            {
                if ((bool)(object)m_scroller)
                {
                    m_scroller.ScrollContainer = null;
                }
                m_scroller = value;
                if ((bool)(object)m_scroller)
                {
                    m_scroller.ScrollContainer = this;
                }
            }
        }
        
        private AgBehavior m_content;
        public AgBehavior Content
        {
            get
            {
                return m_content;
            }
            set
            {
                if (IsInitialized)
                {
                    throw Exception.InvalidOperation("Content property cannot be set after initialization");
                }
                m_content = value;
            }
        }
        public Canvas Container
        {
            get { return (Canvas)Element; }
        }

        private void ComputeMaxScrolls()
        {
            double val = Content.Width - this.Width;
            MaxScrollX = val > 0 ? val : 0;
            val = Content.Height - this.Height;
            MaxScrollY = val > 0 ? val : 0;
        }
        
        private double m_maxScrollX = 0;
        private double m_maxScrollY = 0;

        public double ScrollX
        {
            get
            {
                return - m_contentBox.TranslateX;
            }
            set
            {
                m_contentBox.TranslateX = -value;
            }
        }

        public double ScrollY
        {
            get
            {
                return -m_contentBox.TranslateY;
            }
            set
            {
                m_contentBox.TranslateY = -value;
            }
        }

        public double MaxScrollX
        {
            get
            {
                return m_maxScrollX;
            }
            private set
            {
                if (m_maxScrollX != value)
                {
                    m_maxScrollX = value;
                    RaiseEvent("maxScrollXChanged");
                }
            }
        }
        public double MaxScrollY
        {
            get
            {
                return m_maxScrollY;
            }
            private set
            {
                if (m_maxScrollY != value)
                {
                    m_maxScrollY = value;
                    RaiseEvent("maxScrollYChanged");
                }
            }
        }
        
        private void OnContentSizeChanged(object sender, sea args)
        {
            ComputeMaxScrolls();
        }
        private void OnContentBoxTranslateXChanged(object sender, sea args)
        {
            RaiseEvent("scrollXChanged");
            Debug.Trace("ScrollX: " + ScrollX.ToString());
        }
        private void OnContentBoxTranslateYChanged(object sender, sea args)
        {
            RaiseEvent("scrollYChanged");
            Debug.Trace("ScrollY: " + ScrollY.ToString());
        }


        public void add_ready(seh handler)
        {
            Events.AddHandler("ready", handler);
        }
        public void remove_readyChanged(seh handler)
        {
            Events.RemoveHandler("ready", handler);
        }
        public void add_scrollXChanged(seh handler)
        {
            Events.AddHandler("scrollXChanged", handler);
        }
        public void add_scrollYChanged(seh handler)
        {
            Events.AddHandler("scrollYChanged", handler);
        }
        public void add_maxScrollXChanged(seh handler)
        {
            Events.AddHandler("maxScrollXChanged", handler);
        }
        public void add_maxScrollYChanged(seh handler)
        {
            Events.AddHandler("maxScrollYChanged", handler);
        }

        public void remove_scrollXChanged(seh handler)
        {
            Events.RemoveHandler("scrollXChanged", handler);
        }
        public void remove_scrollYChanged(seh handler)
        {
            Events.RemoveHandler("scrollYChanged", handler);
        }
        public void remove_maxScrollXChanged(seh handler)
        {
            Events.RemoveHandler("maxScrollXChanged", handler);
        }
        public void remove_maxScrollYChanged(seh handler)
        {
            Events.RemoveHandler("maxScrollYChanged", handler);
        }

        public override void Initialize()
        {
            seh onSizeChanged = delegate { ComputeMaxScrolls(); };
            this.add_heightChanged(onSizeChanged);
            this.add_widthChanged(onSizeChanged);
            Canvas canvas = (Canvas)Element;
            try
            {
                UIElementCollection children = canvas.Children;
            }
            catch
            {
                throw Exception.InvalidOperation("Xaml element attached to this behavior must be a Canvas");
            }

            ((Canvas)m_content.Element.GetParent()).Children.Remove(m_content.Element);
            string contentBoxName = GenerateName(Plugin);
            Canvas contentBoxCanvas = UIFactory.CreateCanvas(Plugin.Content.Root, contentBoxName, false);
            Container.Children.Add(contentBoxCanvas);
            contentBoxCanvas.Children.Add(m_content.Element);

            m_contentBox = new Translatable();
            m_contentBox.Element = contentBoxCanvas;
            m_contentBox.Plugin = Plugin;
            m_contentBox.Initialize();
            m_contentBox.TranslateX = 0;
            m_contentBox.TranslateY = 0;


            ComputeMaxScrolls();
            /*
              private seh m_onContentSizeChangedHandler;
        private seh m_onContentBoxTranslateXChangedHandler;
        private seh m_onContentBoxTranslateYChangedHandler;
             * */

            m_onContentSizeChangedHandler = OnContentSizeChanged;
            m_onContentBoxTranslateXChangedHandler = OnContentBoxTranslateXChanged;
            m_onContentBoxTranslateYChangedHandler = OnContentBoxTranslateYChanged;
            m_content.add_heightChanged(m_onContentSizeChangedHandler);
            m_content.add_widthChanged(m_onContentSizeChangedHandler);
            m_contentBox.add_translateXChanged(m_onContentBoxTranslateXChangedHandler);
            m_contentBox.add_translateYChanged(m_onContentBoxTranslateYChangedHandler);

            base.Initialize();
            RaiseEvent("ready");
        }
    }
}